<template>
    <!-- <Timeline
        
    /> -->
    <div class="timeline-editor-engine">
      <Player ref="playerRef" @setPlaying="setPlaying" @onEnded="reciveOnEnded" @setTimelineScale="setTimelineScale" v-if="timelineState" :timeline-state="timelineState"></Player>
      <div style="display: flex;height: 100%;padding-bottom: 32px"> 
        <TimelineEditor
          :scale="timelineScale"
          :scaleWidth="scaleWidth"
          :startLeft="startLeft"
          :autoScroll="true"
          :dragLine="true"
          :gridSnap="true"
          ref="timelineEditorRef"
          :editorData="mockData"
          :effects="mockEffect"
          @change="setData"
          @scroll="setScrollTop"
          :getActionRender="(action, row)=>{
            let child = getAction(action, row)
            // console.log(action,row)
            // console.log(child)
            return child
          }"
        ></TimelineEditor>
      </div>
      
    </div>
    
</template>
<script>
import { applyVueInReact,applyPureReactInVue,getReactNode} from 'veaury'
// 这是一个React组件
import { Timeline } from '@xzdarcy/react-timeline-editor';
import playerComponent from './player/index.vue'
import itemComponent from './item/index.vue'
import '@/styles/timeLineEditor.less';
import { scaleWidth,startLeft } from './data/timelineData';
import {h,render,ref,defineExpose} from 'vue'
import motionControl from './controls/motionControl.ts'
import actionControl from './controls/actionControl.ts'
import lottieControl from './controls/lottieControl.ts'
import audioControl from './controls/audioControl.ts'
import visemeControl from './controls/visemeControl.ts'
import { useSceneStore } from '@/stores/scene'
import {mittTypes,componentTypes} from "@/util/types"
import mitt from 'mitt';
var _this;
export default {
  components: {
    // 使用高阶组件 'applyReactInVue'
    // TimelineEditor: applyReactInVue(Timeline),
    // 现在推荐使用纯净模式的 'applyPureReactInVue'
    TimelineEditor: applyPureReactInVue(Timeline),
    Player:playerComponent,
    // itemControlList:itemControlList
  },
  setup() {
    
    return {
      foo: ref('Hello!'),
      timelineEditorRef: ref(),
      timelineState: ref(),
      scrollTop: ref(0),
      timelineScale: ref(5),
      motionControl:new motionControl(),
      actionControl:null,
      visemeControl:null,
      audioControl:new audioControl(),
      lottieControl:new lottieControl(),
      sceneStore:useSceneStore(),
      isPlaying : false,
      onEnded:null,
      onSpeechEnded:null,
      
      play(){
        this.$refs.playerRef.play();
        
      },
      pause(reset){
        _this.audioControl.stop();
        _this.visemeControl.stop()
        _this.actionControl.stop()
        this.$refs.playerRef.pause(reset);
        
      },
      setPlaying(value){
        _this.isPlaying = value
      },
      reciveOnEnded(){
        console.log('onEnded')
        if(_this.onEnded){
          _this.onEnded()
        }
      },
      reciveOnSpeechEnded(){
        console.log('onEnded')
        if(_this.onSpeechEnded){
          _this.onSpeechEnded()
        }
      },
      

      mockData:ref([]),
      mockEffect:{
        effectAudio: {
          id: "effectAudio",
          name: "声音",
          source: {
            start: ({ action, engine, isPlaying, time }) => {
              if (isPlaying) {
                const src = (action ).data.src;
                audioControl.start({ id: src, src, startTime: action.start, engine, time });
                
              }
            },
            enter: ({ action, engine, isPlaying, time }) => {
              if (isPlaying) {
                const src = (action ).data.src;
                audioControl.start({ id: src, src, startTime: action.start, engine, time });
              }
            },
            leave: ({ action, engine }) => {
              const src = (action ).data.src;
              audioControl.stop({ id: src, engine });
            },
            stop: ({ action, engine }) => {
              const src = (action ).data.src;
              audioControl.stop({ id: src, engine });
            },
          },
        },
        flow_edit_speech: {
          id: "flow_edit_speech",
          name: "tts",
          source: {
            start: ({ action, engine, isPlaying, time }) => {
              // if (isPlaying) {
              //   let src = (action ).data.src;
              //   if((action ).data.src.indexOf('http')<0){
              //     src = 'https://ai3d.huilan.com'+(action ).data.src;
              //   }
              //   _this.audioControl.start({ id: src, src, startTime: action.start, engine, time });
                
              // }
            },
            enter: ({ action, engine, isPlaying, time }) => {
              const src = (action ).data.src;
             
              const diff = (_this.audioControl.playingId!=src)
              console.log('diff',diff)
              console.log('isPlaying',isPlaying)
              if (isPlaying&&diff&&_this.sceneStore.projectConfig.projectSet.type == 'Web3d') {
                let viseme = _this.sceneStore.currentFlowNode.speechWordsList[0].timelineData.speechData[action.data.visemeIndex].visemeData
                console.log('播放：'+(action ).data.objectName)
                let url = _this.origin+src
                if (src.indexOf('blob')>-1){
                  //大模型取回的url为本地地址
                  url = src
                }
                _this.audioControl.start({ id: src, src:url, startTime: action.start, engine, time,onPlay:function(){
                    //语音开始播放后，播放对应的viseme
                    _this.visemeControl.start({ 
                     viseme: viseme,
                    })
                    
                } });
                
              }
            },
            leave: ({ action, engine }) => {
              const src = _this.origin+(action ).data.src;
              if(action.data.lastWord&&_this.sceneStore.projectConfig.projectSet.type == 'Web3d'){
                _this.audioControl.playingId = null;
                _this.visemeControl.stop()
                if(action.data.type&&action.data.type=='dynamic'){
                  _this.reciveOnSpeechEnded();
                }
              }
             
            },
            stop: ({ action, engine }) => {
              if(_this.sceneStore.projectConfig.projectSet.type == 'Web3d'){
                const src = _this.origin+(action ).data.src;
                _this.audioControl.stop({  engine });
                _this.visemeControl.stop()
              }
              
            },
          },
        },
        flow_edit_audio: {
          id: "flow_edit_audio",
          name: "音频",
          source: {
            start: ({ action, engine, isPlaying, time }) => {
              if (isPlaying) {
                const src = _this.origin+(action ).data.src;
                _this.audioControl.start({ id: action.id, src, startTime: action.start, engine, time });
                
              }
            },
            enter: ({ action, engine, isPlaying, time }) => {
              const src = (action ).data.src;
              if (isPlaying&&_this.audioControl.playingId!=src) {
                console.log(src)
                // let viseme = _this.sceneStore.currentFlowNode.speechWordsList[0].timelineData.speechData[action.data.visemeIndex].visemeData
                // _this.visemeControl.start({ 
                //   viseme: viseme,
                //  })
                _this.audioControl.start({ id: action.id, src:_this.origin+src, startTime: action.start, engine, time });
              }
            },
            leave: ({ action, engine }) => {
              const src = _this.origin+(action ).data.src;
              // if(action.data.lastWord){
                _this.audioControl.stop({ id: action.id, engine });
              //   _this.visemeControl.stop()
              // }
             
            },
            stop: ({ action, engine }) => {
              const id = action.id;
              _this.audioControl.stop({ engine ,id});
              // _this.visemeControl.stop()
            },
          },
        },
        flow_edit_image: {
          id: componentTypes.FLOW_EDIT.IMAGE,
          name: "图片",
          source: {
            start: ({ action, engine, isPlaying, time }) => {
              if (isPlaying) {
                // const src = (action ).data.src;
                console.log('start',action)
                // audioControl.start({ id: src, src, startTime: action.start, engine, time });
                _this.motionControl.start({ action: action })
              }
            },
            update: ({ action, time }) => {
              const src = (action ).data.src;
              // _this.motionControl.update({ action: action,time:time })
              // lottieControl.update({ id: src, src, startTime: action.start, endTime: action.end, time });
            },
            enter: ({ action, engine, isPlaying, time }) => {
              const src = (action ).data.src;
                _this.motionControl.enter({ action: action })
                _this.motionControl.start({ action: action })
            },
            leave: ({ action, engine }) => {
              const src = (action ).data.src;
              _this.motionControl.leave({ action: action })
              // audioControl.stop({ id: src, engine });
            },
            stop: ({ action, engine }) => {
              const src = (action ).data.src;
              _this.motionControl.stop({ action: action })
              // audioControl.stop({ id: src, engine });
            },
          },
        },
        flow_edit_video: {
          id: componentTypes.FLOW_EDIT.VIDEO,
          name: "视频",
          source: {
            start: ({ action, engine, isPlaying, time }) => {
              if (isPlaying) {
                // const src = (action ).data.src;
                console.log('start',action)
                // audioControl.start({ id: src, src, startTime: action.start, engine, time });
                _this.motionControl.start({ action: action })
              }
            },
            update: ({ action, time }) => {
              const src = (action ).data.src;
              
              // _this.motionControl.update({ action: action,time:time })
              // lottieControl.update({ id: src, src, startTime: action.start, endTime: action.end, time });
            },
            enter: ({ action, engine, isPlaying, time }) => {
              const src = (action ).data.src;
                _this.motionControl.enter({ action: action })
                _this.motionControl.start({ action: action })
            },
            leave: ({ action, engine }) => {
              const src = (action ).data.src;
              _this.motionControl.leave({ action: action })

              // audioControl.stop({ id: src, engine });
            },
            stop: ({ action, engine }) => {
              const src = (action ).data.src;
              _this.motionControl.stop({ action: action })

              // audioControl.stop({ id: src, engine });
            },
          },
        },
        flow_edit_action: {
          id: componentTypes.FLOW_EDIT.ACTION,
          name: "动作",
          source: {
            start: ({ action, engine, isPlaying, time }) => {
              console.log('start',action)
              if (isPlaying) {
                // const src = (action ).data.src;
                
                _this.actionControl.start({ action: action })
              }
            },
            update: ({ action, time }) => {
              const src = (action ).data.src;
              // _this.actionControl.update({ action: action,time:time-action.start })

              // _this.actionControl.update({ action: action,time:time })
            },
            enter: ({ action, engine, isPlaying, time }) => {
              console.log('enter',action)
              if (isPlaying) {
                const src = (action ).data.src;
                _this.actionControl.start({ action: action })
              }
            },
            leave: ({ action, engine }) => {
              const src = (action ).data.src;
              _this.actionControl.leave(action)
            },
            stop: ({ action, engine }) => {
              const src = (action ).data.src;
              _this.actionControl.stop(action)
            },
          },
        },
        flow_edit_svgAnim: {
          id: componentTypes.FLOW_EDIT.SVGANIM,
          name: "动画",
          source: {
            start: ({ action, engine, isPlaying, time }) => {
              if (isPlaying) {
                // const src = (action ).data.src;
                console.log('start',action)
                _this.motionControl.start({ action: action })
              }
            },
            update: ({ action, time }) => {
              const src = (action ).data.src;
              _this.lottieControl.update({ id: action.id, src, startTime: action.start, endTime: action.end, time });
              if(!_this.isPlaying){
                // _this.motionControl.update({ action: action,time:time })
                _this.motionControl.update({ action: action,time:time })

              }
            },
            enter: ({ action, engine, isPlaying, time }) => {
              const src = (action ).data.src;
              _this.lottieControl.enter({ action: action, src, startTime: action.start, endTime: action.end, time });
              _this.motionControl.enter({ action: action })
              _this.motionControl.start({ action: action })
              // _this.motionControl.update({ action: action,time:time })

            },
            leave: ({ action, time  }) => {
              const src = (action ).data.src;
              _this.lottieControl.leave({ id: src, startTime: action.start, endTime: action.end, time });
              _this.motionControl.leave({ action: action })
            },
            stop: ({ action, engine }) => {
              // const src = (action ).data.src;
              // _this.lottieControl.stop()
              _this.motionControl.stop({ action: action })
            },
          },
        },
        flow_edit_event: {
          id: componentTypes.FLOW_EDIT.EVENT,
          name: "事件",
          source: {
            start: ({ action, engine, isPlaying, time }) => {
              if (isPlaying) {
                // console.log('event start', action)
                // 触发事件开始逻辑
                // _this.emitter.emit(mittTypes.EVENT.TRIGGER_EVENT, {
                //   action: action,
                //   type: 'start',
                //   time: time
                // })
              }
            },
            update: ({ action, time }) => {
              // 事件更新逻辑
              // console.log('event update', action, time)
              // _this.emitter.emit(mittTypes.EVENT.TRIGGER_EVENT, {
              //     action: action,
              //     type: 'update',
              //     time: time
              //   })
            },
            enter: ({ action, engine, isPlaying, time }) => {
              // if (isPlaying) {
                
              // }
              console.log('custom-event enter', action)
              // 向父网页发送事件数据
              _this.sendEventToParent(action, 'custom-event', time)
            },
            leave: ({ action, time }) => {
              // console.log('event leave', action)
              // 向父网页发送事件数据
              // _this.sendEventToParent(action, 'leave', time)
            },
            stop: ({ action, engine }) => {
              // console.log('event stop', action)
              // 触发事件停止逻辑
              // _this.emitter.emit(mittTypes.EVENT.TRIGGER_EVENT, {
              //   action: action,
              //   type: 'stop'
              // })
            },
          },
        },
      },
      setCurrentTime(time){
        _this.timelineState.setTime(time)
      },
      setData:function(data){
        // console.log(data)
        //拖拽左右调整收尾时间时 同步到keyframe上的time
        // let finded = null;
        // for(var i=0;i<data.length;i++){
        //   if(finded){
        //     break;
        //   }
        //   let list;
        //   switch(data[i].actions[0].effectId){
        //     case componentTypes.FLOW_EDIT.IMAGE:
        //       list = _this.sceneStore.currentFlowNode.imageList;
        //     case componentTypes.FLOW_EDIT.VIDEO:
        //       list = _this.sceneStore.currentFlowNode.videoList;

        //       for(var j=0;j<list.length;j++){
                
        //         if(data[i].id == list[j].timelineData.id){
        //           let length = list[j].timelineData.actions[0].data.keyFrames.length;
        //           // let timedel = data[i].actions[0].start-list[j].timelineData.actions[0].data.keyFrames[0].time
        //           let starttime = list[j].timelineData.actions[0].data.keyFrames[0].time;
        //           // console.log(starttime)
        //           list[j].timelineData.actions[0].data.keyFrames.forEach(function(element){
        //             let del = element.time-starttime
        //             element.time = data[i].actions[0].start+del
        //           })
        //           list[j].timelineData.actions[0].data.keyFrames[0].time = data[i].actions[0].start
        //           list[j].timelineData.actions[0].data.keyFrames[length-1].time = data[i].actions[0].end
        //           finded = true;
        //           break;
        //         }
        //       }
        //       break;
        //     case componentTypes.FLOW_EDIT.ACTION:
        //       list = _this.sceneStore.currentFlowNode.actionList;
        //       break;
        //   }
          
        //   // console.log(list)
        // }
        
      },
      setScrollTop:function(data){
        // console.log(data)
        // this.scrollTop = data.scrollTop
        _this.$refs.itemControlListRef&&_this.$refs.itemControlListRef.setScrollTop(data.scrollTop)
      },
      setTimelineScale:function(data){
        // console.log(data)
        // this.scrollTop = data.scrollTop
        _this.timelineScale = data
      },
      setTimelineScrollTop:function(scrollTop){
        console.log(scrollTop)
        // this.scrollTop = data.scrollTop
        _this.$refs.timelineEditorRef.__veauryReactRef__.setScrollTop(scrollTop)
      },
      getAction(action, row){
        let effect = h(itemComponent,{action: action,row:row,timelineScale:this.timelineScale})
        // let newdom = document.createElement('div')
        // render(effect,newdom)
        return getReactNode(effect);
        // if (action.effectId === 'effectAudio') {
        //   return getReactNode(effect);
        // } else if (action.effectId === 'effectImage') {
        //   return getReactNode(effect);
        // }
      },
      onUpdateRender(){
        if(!_this.sceneStore.currentFlowNode){
          return;
        }
        setTimeout(() => {
          _this.mockData = []
          _this.sceneStore.currentFlowNode.imageList.forEach(element => {
            element.timelineData.actions.forEach(function(action){
              action.data.title = element.title;
            })
            _this.mockData.push(element.timelineData)
          });
          _this.sceneStore.currentFlowNode.videoList.forEach(element => {
            element.timelineData.actions.forEach(function(action){
              action.data.title = element.title;
            })
            _this.mockData.push(element.timelineData)
          });
          _this.sceneStore.currentFlowNode.actionList.forEach(element => {
            // element.timelineData.actions[0].data.title = element.title;
            _this.mockData.push(element.timelineData)
          });
          _this.sceneStore.currentFlowNode.svgAnimList.forEach(element => {
            element.timelineData.actions.forEach(function(action){
              action.data.title = element.title;
            })
            _this.mockData.push(element.timelineData)
          });
          _this.sceneStore.currentFlowNode.audioList.forEach(element => {
            element.timelineData.actions.forEach(function(action){
              action.data.title = element.title;
            })
            _this.mockData.push(element.timelineData)
          });
          _this.sceneStore.currentFlowNode.speechWordsList.forEach(element => {
            // element.timelineData.actions[0].data.title = element.title;
            _this.mockData.push(element.timelineData)
          });
          _this.sceneStore.currentFlowNode.eventList&&_this.sceneStore.currentFlowNode.eventList.forEach(element => {
            // element.timelineData.actions[0].data.title = element.title;
            _this.mockData.push(element.timelineData)
          });

          console.log( _this.mockData)
        });
        
      },
      onAddKeyframe(keyframeData){
        if(!_this.sceneStore.currentFlowNode||!_this.sceneStore.currentAttrItem){
          return;
        }
        let list;
        switch(_this.sceneStore.currentAttrItem.type){
          case componentTypes.FLOW_EDIT.IMAGE:
          list = _this.sceneStore.currentFlowNode.imageList
            break;
          case componentTypes.FLOW_EDIT.VIDEO:
          list = _this.sceneStore.currentFlowNode.videoList
            break;
        }
        list.forEach(function(element,idx){
          if(element.id == _this.sceneStore.currentAttrItem.data.id){
            if(keyframeData.index>=element.timelineData.actions[0].data.keyFrames.length){
              element.timelineData.actions[0].end = keyframeData.data.time
            }
            element.timelineData.actions[0].data.keyFrames.splice(keyframeData.index,0,keyframeData.data)
          }
        })
        _this.onUpdateRender()
      },
      // 向父网页发送事件数据的方法
      sendEventToParent(action, actionType, time) {
        // 构建事件列表数据
        const eventList = [];
        
        if (action && action.data && action.data.eventList) {
          action.data.eventList.forEach(event => {
            const eventData = {
              id: event.id,
              name: event.name,
              params: {}
            };
            
            // 根据参数类型转换值
            if (event.params) {
              event.params.forEach(param => {
                let value = param.value;
                switch (param.type) {
                  case 'number':
                    value = parseFloat(param.value) || 0;
                    break;
                  case 'boolean':
                    value = param.value === 'true' || param.value === true;
                    break;
                  case 'string':
                  default:
                    value = String(param.value || '');
                    break;
                }
                eventData.params[param.name] = value;
              });
            }
            
            eventList.push(eventData);
          });
        }
        
        // 构建消息数据
        const messageData = {
          type: 'timeline-event',
          actionType: actionType,
          data:{
            time: time,
            eventList: eventList
          }
        };
        
        // 向父窗口发送消息
        if (window.parent && window.parent !== window) {
          window.parent.postMessage(messageData, '*');
        }
      }
    }
  },
  props:{
    flowNode:{
      type:Object,
      default:null
    }
  },
  mounted(){
    _this = this;
    this.sceneStore.currentFlowNode = this.flowNode
    this.timelineEditorRef.$el.style.width = "100%"
    
    // this.timelineState = this.$refs.timelineEditorRef
    // console.log(this.timelineState)

    setTimeout(()=>{
      console.log(this.$refs.timelineEditorRef.__veauryReactRef__)
      this.timelineState = this.$refs.timelineEditorRef.__veauryReactRef__
      this.sceneStore.currentTimelineTime = 0;
      
    })

    
    if(this.sceneStore.currentFlowNode){
      this.sceneStore.currentFlowNode.imageList.forEach(element => {
        this.mockData.push(element.timelineData)
      });
      this.sceneStore.currentFlowNode.videoList.forEach(element => {
        this.mockData.push(element.timelineData)
      });
      this.sceneStore.currentFlowNode.actionList.forEach(element => {
        this.mockData.push(element.timelineData)
      });
      this.sceneStore.currentFlowNode.svgAnimList.forEach(element => {
        this.mockData.push(element.timelineData)
      });
      this.sceneStore.currentFlowNode.eventList.forEach(element => {
        this.mockData.push(element.timelineData)
      });
    }
    
    this.emitter.on(mittTypes.TIMELINE.UPDATE_TIMELINE_DATA,this.onUpdateRender)
    this.emitter.on(mittTypes.TIMELINE.MUTE_AUDIO,function(){
      _this.audioControl.mute();
    })
    this.emitter.on(mittTypes.TIMELINE.UNMUTE_AUDIO,function(){
      _this.audioControl.unmute();
    })
    this.actionControl = new actionControl(this.emitter)
    this.visemeControl = new visemeControl(this.emitter)
  }
}
</script>